管中规豹-Oculus App生态分析
Oculus有着一个非常庞大的Integration SDK,其中又涵盖了Unity 3D,Unread和Native的开发,而这些部分又可以叠加OpenXR和非OpenXR。
在VR设备领域,Oculus是绝对的标杆和对标的竞品,厂商可以通过分析Oculus App的集成情况来窥探当前App的一个生态布局。
- OpenXR在开发者眼中到底是否需要支持?
- 有多少应用开始集成OpenXR了?
- Unity和Unreal到底哪个引擎的使用者占比更多?
- 其他的引擎在实际VR开发中是怎么样的情况?
- 当前App中使用的哪个Oculus SDK版本最多?
- 开发者是否会不断跟进Oculus新发布的SDK?
- ……
App的来源
支持正版:
- Oculus App store:https://www.oculus.com/experiences/quest/
实际情况是每一款游戏的价格都不便宜,所以从非正规渠道要到了一些破解的游戏url下载地址,大约一共有380+款,实际最终下载从成功的是218款,一共是584G,编写脚本+下载一共耗时3天。
分析的过程
下载的包中,我们需要区分当前是资源包(OBB)还是安装包(APK),我们的分析手段仅限于安装包。
Oculus SDK版本
Oculus Integration SDK的构成主要有7大部分:
- OVRPlugin:Oculus VR Plugin,基于Unity/Unreadl/OpenXR的Impl
- Interaction SDK:手势交互,裸手手势识别
- Platform SDK:提供平台内容的sdk,比如Home资讯,游戏内排名展示等
- Voice SDK:语音ASR,NLP
- Meta Avatars SDK:Facebook的虚拟人SDK
- Tracked keyboard SDK:虚拟键盘SDK
- Audio SDK:空间音频SDK
以上的部分是我自己的理解,参考的依据是来自Oculus Developer Guider和SDK Relase note:
https://developer.oculus.com/downloads/package/unity-integration/43.0/
另外,根据Oculus Unity Integration SDK的拆解和逆向分析,得到了大致如下的调用关系链:
其中Unity XR Plugin中Subsystems的介绍摘自Unity官方的介绍:https://docs.unity3d.com/Manual/XRPluginArchitecture.html
Oculus XR Plugin的实现是由
libOVRPlugin.so
来完成的通过libOVRPlugin.so,Oculus统一了OpenXR方案与Vrapi(非OpenXR)方案对OpenXR Runtime的依赖关系
一个大胆的猜测,其实OpenXR中out of process的架构,是否源自于Oculus本身的这套架构实现?
有了以上的认知,我们在做分析的时候就可以直接从libOVRPlugin.so
入手了,通过分析这个so库我们可以了解当前的安装包(APK)中使用的到底是哪一个SDK版本。
解构libOVRPlugin.so
首先,我是怎么知道libOVRPlugin.so中会带有版本信息的呢?
其实这个问题是靠猜的,根据之前的代码/工作经验,一般在so库中也是需要标识版本的,那么就用使用一些常量字段或者是编译flag,这些字段一般都是会直接编到代码中明文可见的。
在实际过程中,我使用vim
工具先直接暴力查看了一下,发现果然是存在的:
如果是这样的话,一切就好办了,我们可以使用objdump
工具先对整个so库中的section做一个dump,然后再去dump文件中找对应的关键字,最后把这一套方法写成固定脚本,就可以快速解析所有的安装包(APK)了。
使用objdump
其实也没有什么技巧,可以直接从AOSP
工程中找到对应的toolchain,一般来说路径是这样的,需要注意的是区分32 or 64bit:
64bit:
/android-ndk-r20/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/aarch64-linux-android/bin/objdump
32bit:
/android-ndk-r20/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/arm-linux-androideabi/bin/objdump
尝试使用objdump -s
命令dump出so库的所有section,然后再去搜一下关键字1.61.0
,发现这个字段出现在rodata
的最开始的部分,那么这个就很好办了。
如上图所示,这个安装包(APK)中使用到的libOVRPlugin.so
的版本就是1.61.0
。
查找SDK的版本
这个也是一个死功夫,其实就是把Oculus官网的SDK都撸一遍,然后拿到对应关系。
由于官网的下拉菜单里面只保留了部分的SDK版本,所以没有办法获取到全部的信息,我尝试拼接url的方式弄了一下大概是这么多。
拼接的方式如下,部分是空的,也部分需要修改后缀的0为1,2,等等的
https://developer.oculus.com/downloads/package/unity-integration/43.0/
https://developer.oculus.com/downloads/package/unity-integration/42.0/
……
https://developer.oculus.com/downloads/package/unity-integration/31.2/
https://developer.oculus.com/downloads/package/unity-integration/11.0/
解构libovrplatformloader.so
这个部分跟libOVRPlugin.so
的很类似,先是使用vim(string)读出其中的内容:
|
|
这样的话就可以根据该字段来获取对应的版本信息了,另外一个方法还是通过objdump的方式来做,但效果是一样的。
Integration SDK和OVRPlugin的对应关系
遍历了一下官网的信息,可以得到如下的对应关系。
Integration SDK版本号 | libOVRPlugin版本号 | 发布日期 |
---|---|---|
12.0 | 1.44.0 | Dec 20, 2019 |
13.0 | 1.45.0 | Feb 7, 2020 |
14.0 | 1.46.0 | Mar 12, 2020 |
15.0 | 1.47.0 | Apr 7, 2020 |
16.0 | 1.48.0 | Apr 29, 2020 |
17.0 | 1.49.0 | May 27, 2020 |
18.0 | 1.50.0 | Jul 7, 2020 |
19.0 | 1.51.0 | Aug 4, 2020 |
20.0 | 1.52.0 | Sep 3, 2020 |
20.1 | 1.52.1 | Oct 6, 2020 |
23.1 | 1.55.1 | Dec 19, 2020 |
25.0 | 1.57.0 | Feb 20, 2021 |
27.0 | 1.59.0 | Apr 14, 2021 |
28.0 | 1.60.0 | Apr 29, 2021 |
29.0 | 1.61.0 | May 25, 2021 |
31.2 | 1.63.1 | Aug 21, 2021 |
32.0 | 1.64.0 | Aug 31, 2021 |
33.0 | 1.65.0 | Sep 29, 2021 |
34.0 | 1.66.0 | Nov 12, 2021 |
35.0 | 1.67.0 | Dec 7, 2021 |
37.0 | 1.69.0 | Feb 2, 2022 |
38.0 | 1.70.0 | Mar 23, 2022 |
39.0 | 1.71.0 | Apr 28, 2022 |
40.0 | 1.72.0 | Jun 1, 2022 |
41.0 | 1.73.0 | Jun 23, 2022 |
42.0 | 1.74.0 | Jul 20, 2022 |
43.0 | 1.75.0 | Aug 24, 2022 |
区分U3D/UE4/OpenXR
这个部分还是比较简单的,我们可以通过查询安装包(APK)的so库中是否包含对应引擎的特征so。
- Unity 3D引擎:
libunity.so
- Unreal Engine4引擎:
libUE4.so
- OpenXR平台:
libopenxr_loader.so
结论
方法
- 通过结构
libOVRPlugin.so
得到了对应的Oculus SDK版本信息 - 通过遍历so库得到当前引擎是U3D/UE4,亦或是否基于OpenXR进行开发
数据
SDK分布
- SDK版本集中在19 - 35之间,对应的时间大约为2020.8到2021.11,其中SDK版本19 - 29 ,一共占比 48%(102/212)
游戏引擎分布
- Unity 3D Engine:165款
- Unreal Engine 4:47款
- Other:6款
OpenXR
在218款游戏中,一共有14款游戏是基于OpenXR开发的。